package com.leyou.search.service.impl;

import com.leyou.common.dto.PageDTO;
import com.leyou.item.clients.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpecParamDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.search.entity.Goods;
import com.leyou.search.repository.GoodsRepository;
import com.leyou.search.service.IndexService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class IndexServiceImpl implements IndexService {
    @Autowired
    private ItemClient itemClient;
    @Autowired
    private GoodsRepository repository;

    //把SpuDTO转化为goods
    @Override
    public Goods buildGoods(SpuDTO spuDTO){
     Goods goods=new Goods();
        BeanUtils.copyProperties(spuDTO,goods);
        String categoryNames=StringUtils.join(
                StringUtils.split(spuDTO.getCategoryName(),"/"), " ");
       //在其title中加入分类以及品牌信息
        String newTitle=spuDTO.getTitle()+categoryNames+" "+spuDTO.getBrandName();
        goods.setTitle(newTitle);
        //cayegoryId
        goods.setCategoryId(spuDTO.getCid3());
        //根据spuId查询对应的sku信息
        List<SkuDTO>skuDTOS=this.itemClient.querySkuBySpuId(spuDTO.getId());
        //TODO:updateTime

        //image  从多个sku中取出第0个  获取其图片信息  sku如果有多个图片  之间以逗号分隔 如果逗号不存在  则获取所有内容
        goods.setImage(StringUtils.substringBefore(skuDTOS.get(0).getImages(),","));

        Set<Long>price=new HashSet<>();
        Long sold=0L;
        //prices

        //sold
        //获取到spu下所有的sku的价格以及销量
        for (SkuDTO skuDTO : skuDTOS) {
            price.add(skuDTO.getPrice());
            sold+=skuDTO.getSold();
        }
        goods.setPrices(price);
         goods.setSold(sold);

         //suggestion
        List<String> suggestion = new ArrayList<>(
                Arrays.asList(StringUtils.split(spuDTO.getCategoryName(), "/")));
        suggestion.add(spuDTO.getName());
        suggestion.add(spuDTO.getBrandName());
        goods.setSuggestion(suggestion);
        //1.自动补全的提示字段
        List<Map<String,Object>>specs=new ArrayList<>();
        //根据spuId以及可搜索  查询规格可搜索参数
        List<SpecParamDTO>specValue=this.itemClient.querySpecValue(spuDTO.getId(),true);

        //把查询到的可搜索规格参数取其name 以及value封装给specs

        specValue.forEach(spv->{
            Map<String,Object>spec=new HashMap<>();

            spec.put("name",spv.getName());
            //value赋值时不要直接赋值
            spec.put("value",chooseSegment(spv));
            specs.add(spec);
        });
        goods.setSpecs(specs);
        return goods;
    }

    @Override
    public void saveGoodsById(Long spuId) {
        SpuDTO spuDTO = this.itemClient.pageQuery(1, 1, null, null, null, spuId).getItems().get(0);
        Goods goods = buildGoods(spuDTO);
        this.repository.save(goods);
    }

    @Override
    public void deleteGoodsById(Long spuId) {
        this.repository.deleteById(spuId);
    }

    private Object chooseSegment(SpecParamDTO p) {
        Object value = p.getValue();
        if (value == null || StringUtils.isBlank(value.toString())) {
            return "其它";
        }
        if (!p.getNumeric() || StringUtils.isBlank(p.getSegments()) || value instanceof Collection) {
            return value;
        }
        double val = parseDouble(value.toString());
        String result = "其它";
        // 保存数值段
        for (String segment : p.getSegments().split(",")) {
            String[] segs = segment.split("-");
            // 获取数值范围
            double begin = parseDouble(segs[0]);
            double end = Double.MAX_VALUE;
            if (segs.length == 2) {
                end = parseDouble(segs[1]);
            }
            // 判断是否在范围内
            if (val >= begin && val < end) {
                if (segs.length == 1) {
                    result = segs[0] + p.getUnit() + "以上";
                } else if (begin == 0) {
                    result = segs[1] + p.getUnit() + "以下";
                } else {
                    result = segment + p.getUnit();
                }
                break;
            }
        }
        return result;
    }

    private double parseDouble(String str) {
        try {
            return Double.parseDouble(str);
        } catch (Exception e) {
            return 0;
        }
    }
    @Override
    public void loadData() {
        //删除既有的索引库
    repository.deleteIndex();
    //重建索引库
        repository.createIndex("{\n" +
                "  \"settings\": {\n" +
                "    \"analysis\": {\n" +
                "      \"analyzer\": {\n" +
                "        \"my_pinyin\": {\n" +
                "          \"tokenizer\": \"ik_smart\",\n" +
                "          \"filter\": [\n" +
                "            \"py\"\n" +
                "          ]\n" +
                "        }\n" +
                "      },\n" +
                "      \"filter\": {\n" +
                "        \"py\": {\n" +
                "\t\t  \"type\": \"pinyin\",\n" +
                "          \"keep_full_pinyin\": true,\n" +
                "          \"keep_joined_full_pinyin\": true,\n" +
                "          \"keep_original\": true,\n" +
                "          \"limit_first_letter_length\": 16,\n" +
                "          \"remove_duplicated_term\": true\n" +
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  },\n" +
                "  \"mappings\": {\n" +
                "    \"properties\": {\n" +
                "      \"id\": {\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"suggestion\": {\n" +
                "        \"type\": \"completion\",\n" +
                "        \"analyzer\": \"my_pinyin\",\n" +
                "        \"search_analyzer\": \"ik_smart\"\n" +
                "      },\n" +
                "      \"title\":{\n" +
                "        \"type\": \"text\",\n" +
                "        \"analyzer\": \"my_pinyin\",\n" +
                "        \"search_analyzer\": \"ik_smart\"\n" +
                "      },\n" +
                "      \"image\":{\n" +
                "        \"type\": \"keyword\",\n" +
                "        \"index\": false\n" +
                "      },\n" +
                "      \"updateTime\":{\n" +
                "        \"type\": \"date\"\n" +
                "      },\n" +
                "      \"specs\":{\n" +
                "        \"type\": \"nested\",\n" +
                "        \"properties\": {\n" +
                "          \"name\":{\"type\": \"keyword\" },\n" +
                "          \"value\":{\"type\": \"keyword\" }\n" +
                "        }\n" +
                "      }\n" +
                "    }\n" +
                "  }\n" +
                "}");
        int page=1;
        //查询spu 分页查询 结束的条件为翻页的页码大于总页数
        while (true){
            PageDTO<SpuDTO> spuDTOPageDTO=
              this.itemClient.pageQuery(page,50,null,null,null,null);
          //TODO:移到最下边

             //把查询到的spuDTO转化为goods集合
            List<Goods>goodsList=spuDTOPageDTO.getItems()
                    .stream()
                    .map(spuDTO -> buildGoods(spuDTO))
                    .collect(Collectors.toList());
             //保存
            repository.saveAll(goodsList);
            page++;
            if (page>spuDTOPageDTO.getTotalPage()){
                break;
            }
        }
    }
}
